package com.treasure.mall.biz.service.core.user;

import com.treasure.mall.biz.base.SearchableCrudService;
import com.treasure.mall.biz.dto.condition.UserSearchCondition;
import com.treasure.mall.biz.dto.user.*;
import com.treasure.mall.biz.entity.auth.SystemManager;
import com.treasure.mall.biz.entity.user.UserPO;
import com.treasure.mall.biz.vo.user.TeamSummaryVO;
import com.treasure.mall.biz.vo.user.UserStatisticsVO;
import com.treasure.mall.biz.vo.user.UserVO;
import com.treasure.mall.biz.vo.user.WalletVO;
import com.treasure.mall.zbq.common.base.TwoTuple;
import com.treasure.mall.zbq.common.ienum.user.UserEnums;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 *
 * +---------------------------------------------------------
 * * @package: com.treasure.mall.biz.service.core.user
 * * @author: guomw (guomwchen@foxmail.com)
 * * @date: 2020/6/11 10:42
 * * @since: V1.0.0
 * +---------------------------------------------------------
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 * Copyright 2019-2022 com.treasure.mall.biz.service.core.user Inc. All rights reserved.
 */
public interface UserService extends SearchableCrudService<UserPO, Long> {

    UserPO findById(Long userId);

    UserPO findByUnionId(String unionId);

    /**
     * 根据上线ID获取上线用户
     *
     * @param userId
     * @return
     */
    UserPO findByParentId(Long userId);

    /**
     * 根据token 获取用户数据
     *
     * @param token
     * @return
     */
    UserPO findByToken(String token);


    /**
     * 根据用户名得到用户实体
     *
     * @param username 用户名
     * @return UserPO
     */
    UserPO findByUsername(String username);

    /**
     * 我的下线
     *
     * @param condition 筛选对象
     * @return list
     */
    List<UserPO> findChildren(UserSearchCondition condition);

    /**
     * 查询所有上级用户
     *
     * @param userId 用户id
     * @return 所有上级
     */
    List<UserPO> getSuperiorUserList(Long userId);

    /**
     * 修改用户真实姓名
     *
     * @param userId
     * @param name
     */
    void modifyUserRealName(Long userId, String name);

    /**
     * 根据code获取用户信息
     *
     * @param code
     * @return
     */
    UserVO loginByWechatCode(String code);

    /**
     * 微信授权登录
     *
     * @param dto
     */
    UserVO loginAsWechatApp(LoginDTO dto) throws WxErrorException;

    /**
     * app微信授权登录
     *
     * @param dto
     * @return
     */
    UserVO loginAsApp(AppLoginDTO dto);

    /**
     * App 授权绑定微信
     *
     * @param dto
     * @return
     */
    UserVO appAuthWechat(AppLoginDTO dto);

    /**
     * 手机登录，绑定手机
     *
     * @param dto
     * @return
     */
    UserVO loginAsAppBindMobile(AppLoginAsMobileDTO dto);

    /**
     * 获取当前用户信息
     *
     * @param userId     当前用户ID
     * @param fromUserId 邀请用户ID
     * @return
     */
    UserVO who(Long userId, Long fromUserId);

    /**
     * 修改用户信息
     *
     * @param dto
     */
    void modifyUserInfo(ModifyUserDTO dto);

    TeamSummaryVO inviteSummary(Long userId);

    /**
     * 我的团队概要
     *
     * @param userId
     * @param selectDr 是否查询达人
     * @return
     */
    TeamSummaryVO inviteSummary(Long userId, Boolean selectDr);

    /**
     * 根据id 获取用户余额信息
     *
     * @param userId
     * @return
     */
    WalletVO myBalance(Long userId);


    /**
     * 查找具备返利资格的用户
     *
     * @param userId 购买者ID
     * @return 最多返回两层
     */
    TwoTuple<UserPO, UserPO> getRebateParents(Long userId);

    /**
     * 发起余额修改，未做金额是否超出判断，需调用方自行判断，并记录日志
     *
     * @param modifyBalanceDTO {@link com.treasure.mall.biz.dto.user.ModifyBalanceDTO}
     */
    @Transactional(rollbackFor = Exception.class)
    void modifyBalance(ModifyBalanceDTO modifyBalanceDTO);


    /**
     * 修改用户待入账余额
     *
     * @param modifyBalanceDTO
     */
    @Transactional(rollbackFor = Exception.class)
    void modifyBalanceInFuture(ModifyBalanceDTO modifyBalanceDTO);

    /**
     * 修改锁定余额
     * 目前只有下单时，如果使用了余额支付，需要锁定，其他地方不会锁定
     *
     * @param userId
     * @param amount 扣除为负，添加为正
     */
    void modifyLockBalance(Long userId, BigDecimal amount);

    /**
     * 修改积分
     *
     * @param dto
     */
    @Transactional
    void modifyIntegral(ModifyIntegralDTO dto);

    /**
     * 变更上线
     *
     * @param user             要变更上线的代理商
     * @param targetParentUser 目标上线
     * @param manager          当前系统管理员
     * @return 是否成功
     */
    TwoTuple<Boolean, String> changeParent(UserPO user, UserPO targetParentUser, SystemManager manager);

    /**
     * 升级用户类型，普通和会员
     *
     * @param userId
     */
    void modifyUserType(Long userId);

    /**
     * 升级用户等级，新秀和达人。。
     *
     * @param userId
     */
    void modifyUserLevel(Long userId, UserEnums.UserLevel userLevel);

    /**
     * 修改用户有效支付订单总金额
     *
     * @param userId
     * @param money
     */
    void modifyValidPayOrderSum(Long userId, BigDecimal money);

    /**
     * 升级成功,神经回调成功后，需要要
     *
     * @param userId
     * @param bizOrderId 业务订单ID
     */
    void upgradeSuccess(Long userId, String bizOrderId);

    /**
     * 增加订单金额
     *
     * @param userId
     * @param amount
     */
    void addOrderAmount(Long userId, BigDecimal amount);

    /**
     * 余额转正
     *
     * @param userId
     * @param amount
     */
    @Transactional
    void settleBalance(Long userId, BigDecimal amount, String subOrderId);

    UserStatisticsVO getStatisticsData();

    void upgradeDrLevel();
}
